package ldkxingzhe.l365calendar.other;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.PowerManager;
import android.os.Process;
import android.support.annotation.Nullable;
import android.util.Log;

import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;

import java.util.Date;

import ldkxingzhe.l365calendar.dao.LocationDao;
import ldkxingzhe.l365calendar.model.LocationEntity;

/**
 * 定位服务
 * Created by xingzhe on 16/2/2.
 */
public class LocationService extends Service
        implements BDLocationListener {
    @SuppressWarnings("unused")
    private static final String TAG = "LocationService";

    private Looper mServiceLooper;
    private ServiceHandler mServiceHandler;
    private Object mServiceWakeLockSync = new Object();
    private PowerManager.WakeLock mServiceWakeLock;
    private LocationClient mLocationClient;
    @Override
    public void onCreate() {
        HandlerThread handlerThread = new HandlerThread(TAG, Process.THREAD_PRIORITY_BACKGROUND);
        handlerThread.start();
        mServiceLooper = handlerThread.getLooper();
        mServiceHandler = new ServiceHandler(mServiceLooper);
        mLocationClient = new LocationClient(getApplicationContext());
        initLocationClient();
    }

    private void initLocationClient() {
        LocationClientOption option = new LocationClientOption();
        option.setLocationMode(LocationClientOption.LocationMode.Battery_Saving);
        option.setIsNeedAddress(true);
        option.setIsNeedLocationDescribe(true);
        mLocationClient.setLocOption(option);
        mLocationClient.registerLocationListener(this);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        synchronized (mServiceWakeLockSync){
            if(mServiceWakeLock == null){
                PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
                mServiceWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
                mServiceWakeLock.setReferenceCounted(false);
            }
            mServiceWakeLock.acquire();
        }
        sendLocationRequest();
        return START_NOT_STICKY;
    }

    private void sendLocationRequest() {
        mServiceHandler.removeMessages(HANDLER_FINISH_SERVICE);
        mServiceHandler.sendEmptyMessage(HANDLER_SEND_SINGLE_LOCATION);
        mServiceHandler.sendEmptyMessageDelayed(HANDLER_FINISH_SERVICE, 10000);
    }

    private void sendSingleLocation(){
        mLocationClient.start();
    }

    private int time = 0;
    // runned in a worker thread
    @Override
    public void onReceiveLocation(BDLocation bdLocation) {
        LocationEntity entity = new LocationEntity(bdLocation, new Date().getTime());
        LocationDao locationDao = new LocationDao(getApplicationContext());
        locationDao.insert(entity);
        if((entity.getLocType() == BDLocation.TypeNetWorkException || entity.getLocType() == BDLocation.TypeOffLineLocationFail)
                && time < 5){
            sendLocationRequest();
            time++;
            return;
        }
        mServiceHandler.removeMessages(HANDLER_FINISH_SERVICE);
        mServiceHandler.sendEmptyMessage(HANDLER_FINISH_SERVICE);
        time = 0;
    }

    private static final int HANDLER_SEND_SINGLE_LOCATION = 0;
    private static final int HANDLER_FINISH_SERVICE = 1;
    private final class ServiceHandler extends Handler{
        public ServiceHandler(Looper looper){
            super(looper);
        }
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what){
                case HANDLER_SEND_SINGLE_LOCATION:
                    sendSingleLocation();
                    break;
                case HANDLER_FINISH_SERVICE:
                    finishSelf();
                    break;
            }
        }
    }

    private void finishSelf(){
        Log.v(TAG, "stop self");
        mLocationClient.stop();
        stopSelf();
        synchronized (mServiceWakeLockSync){
            mServiceWakeLock.release();
            mServiceWakeLock = null;
        }
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onDestroy() {
        mServiceLooper.quit();
    }
}
